package tc.de.krawallmann.extension;

import java.util.HashMap;
import java.util.Map;

import org.newdawn.slick.util.Log;

import tc.de.krawallmann.persistence.XMLStorage;
import tc.de.krawallmann.settings.Setting;

/**
 * The Class SettingsExtension manages a program's settings
 *  @author KrawallMann
 * @version 1.0
 */
public class SettingsExtension implements PersistenceExtension, PropertyExtension {
	
	/** The default settings. */
	private transient static final Map<String, Setting<?>> DEFAULT_SETTINGS=new HashMap<String, Setting<?>>();
	
	/** The settings. */
	private transient static Map<String, Setting<?>> settings;
	
	/** The settings file. */
	private transient final String settingsFile;

	/**
	 * Instantiates a new SettingsExtension.
	 * 
	 * @param settingsFile
	 *            the settings file
	 * @param DEFAULT_SETTINGS
	 *            the default settings
	 */
	public SettingsExtension(final String settingsFile,
			final Map<String, Setting<?>> defaultSettings) {
		super();
		if (settingsFile == null) {
			throw new IllegalArgumentException("SettingsExtension file is null!");
		}
		this.settingsFile = settingsFile;
		SettingsExtension.DEFAULT_SETTINGS.putAll(defaultSettings);
	}

	/**
	 * Gets the setting.
	 * 
	 * @param key
	 *            the key
	 * @return the setting
	 */
	public static  boolean getSetting(final String key) {
		boolean ret;
		if (settings.containsKey(key) && (settings.get(key) != null)
				&& (settings.get(key).getType() == Boolean.class)) {
			ret = (Boolean) settings.get(key).getValue();
		} else {
			ret = false;
		}
		return ret;
	}

	/* (non-Javadoc)
	 * @see tc.de.krawallmann.extension.Extension#init()
	 */
	@Override
	public void init() {
		// Not needed!
	}

	/* (non-Javadoc)
	 * @see tc.de.krawallmann.extension.PersistenceExtension#read()
	 */
	@Override
	public boolean read() {
		try {
			settings = XMLStorage.deserialize(settings, settingsFile);
			return true;
		} catch (final Exception e) {
			settings = new HashMap<String, Setting<?>>();
			setDefaults();
			return false;
		}
	}

	/* (non-Javadoc)
	 * @see tc.de.krawallmann.extension.PropertyExtension#setDefaults()
	 */
	@Override
	public void setDefaults() {
		settings.clear();
		for (final java.util.Map.Entry<String, Setting<?>> entry : DEFAULT_SETTINGS.entrySet()) {
			settings.put(entry.getKey(), entry.getValue());
		}
	}

	/**
	 * Sets the setting.
	 * 
	 * @param key
	 *            the key
	 * @param value
	 *            the value
	 */
	@SuppressWarnings("unchecked")
	public static void setSetting(final String key, final boolean value) {
		if (!settings.containsKey(key) || (settings.get(key).getType() == null)) {
			final Setting<Boolean> set = new Setting<Boolean>();
			settings.put(key, set);
		} else {
			if (settings.get(key).getType() == Boolean.class) {
				((Setting<Boolean>) settings.get(key)).setValue(value);
			} else {
				Log.error("Setting " + key + " is not of type boolean!");
			}

		}
	}

	/* (non-Javadoc)
	 * @see tc.de.krawallmann.extension.PersistenceExtension#store()
	 */
	@Override
	public boolean store() {
		try {
			XMLStorage.store(settings, settingsFile);
			return true;
		} catch (final Exception e) {
			return false;
		}
	}

	/* (non-Javadoc)
	 * @see tc.de.krawallmann.extension.Extension#update(long)
	 */
	@Override
	public void update(final long delta) {
		// Not needed!
	}

}
